﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LaoLuo.Web
{
    /// <summary>
    /// 
    /// </summary>
    public class LinkedSelect : IEnumerable<LinkedSelect>
    {
        private static string ToJquerySelector(string id)
        {
            return string.Format(@"$('#{0}')", id);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dataProvider">a url that provides data using by select</param>
        /// <param name="id">select's name and id</param>
        /// <param name="textName">text name</param>
        /// <param name="valueName">value name</param>
        /// <param name="defaultValue">init value</param>
        public LinkedSelect(string dataProvider, string id, string textName = "key", string valueName = "value",
                            object defaultValue = null, string @class = "")
        {
            DataProvider = dataProvider;
            TextName = textName;
            ValueName = valueName;
            Id = id;
            Name = id;
            DefaultValue = defaultValue;
            Class = @class;
        }

        public object DefaultValue { get; set; }
        public string Class { get; set; }
        public string DataProvider { get; set; }
        public string TextName { get; set; }
        public string ValueName { get; set; }
        public string Id { get; set; }
        public string Name { get; set; }
        public LinkedSelect Child { get; set; }
        public LinkedSelect Parent { get; private set; }

        public static string JavaScriptAhead
        {
            get
            {
                return
                    @"
<script type=""text/javascript"">
    // select initiator - By Chester (MIT Licensed)
    $.fn.generateOptions = function(dataProvider, textName, valueName, post) {
        post = post || { };
        post.seed = Math.random();
        var that = this;
        $.getJSON(dataProvider, post, function(data) {
            that.html('<option value="""">请选择</option>');
            for (var i = 0; i < data.Data.length; i++) {
                var d = data.Data[i];
                that.html(that.html() + '<option value=""' + d[valueName] + '"">' + d[textName] + '</option>');
            }
                that.val(that.attr('default')).trigger('change');
        });
    };
</script>";
            }
        }

        #region result

        private List<string> ResultSelectHtmlCollection { get; set; }

        private string ResultJavaScript { get; set; }

        private Tuple<List<string>, string> _result;

        public Tuple<List<string>, string> Result
        {
            get
            {
                if (_result == null)
                {
                    GenerateResult();
                    _result = new Tuple<List<string>, string>(ResultSelectHtmlCollection, ResultJavaScript);
                }

                return _result;
            }
        }

        #endregion

        public LinkedSelect AddChild(LinkedSelect child)
        {
            Child = child;
            Child.Parent = this;
            //Child.DataProvider += string.Format("&{0}=", ValueName);
            return this;
        }

        public string GetChildrenJquerySelector()
        {
            return string.Format(@"$('{0}')", Child.Select(i => "#" + i.Id).GetJoint());
        }

        public IEnumerator<LinkedSelect> GetEnumerator()
        {
            var current = this;
            while (current != null)
            {
                yield return current;
                current = current.Child;
            }
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        private void GenerateResult()
        {
            ResultSelectHtmlCollection = new List<string>();

            var scriptHtml = string.Empty;

            foreach (var node in this)
            {
                ResultSelectHtmlCollection.Add(string.Format(
                    @"<select id=""{0}"" name=""{1}"" default=""{2}"" class=""{3}""></select>",
                    node.Id,
                    node.Name,
                    node.DefaultValue,
                    node.Class
                                                   ));

                //linkedId.AddLast(node.Id);
                var child = node.Child;
                if (child != null)
                {
                    scriptHtml +=
                        string.Format(@"
$('#{0}').change(function () {{
    {1}.empty();
    if($(this).val()){{
    {2}
    }}
}});
",
                                      node.Id,
                                      node.GetChildrenJquerySelector(),
                                      string.Format(@"$('#{0}').generateOptions('{1}', '{2}', '{3}', {{ {4} : {5} }})",
                                                    child.Id, child.DataProvider, child.TextName, child.ValueName,
                                                    node.ValueName, ToJquerySelector(node.Id) + ".val()")
                            );
                }
            }

            ResultJavaScript = string.Format(
                @"
<script type=""text/javascript"">
$(function(){{
{4}
$('#{0}').generateOptions('{1}', '{2}', '{3}');
}});
</script>
",
                Id,
                DataProvider,
                TextName,
                ValueName,
                scriptHtml
                );
        }
    }
}
